#include "mqtt_api.h"
#include "mqtt_client.h"

#define MQTT_DATA_BUFFER_SIZE (1 * 1024)

uint8_t g_MqttSendData[MQTT_DATA_BUFFER_SIZE];

/**
 * @brief  连接服务器的打包函数
 * @param
 * @retval
 * @example
 **/
int ConnectMqtt(char *ClientID, char *Username, char *Password)
{
    int ClientIDLen = strlen(ClientID);
    int UsernameLen = strlen(Username);
    int PasswordLen = strlen(Password);
    int DataLen = 0;
    int Index = 2;
    int i = 0;
    DataLen = 12 + 2 + 2 + ClientIDLen + UsernameLen + PasswordLen;
    g_MqttSendData[0] = 0x10;                              // MQTT Message Type CONNECT
    g_MqttSendData[1] = DataLen;                           // 剩余长度(不包括固定头部)
    g_MqttSendData[Index++] = 0;                           // Protocol Name Length MSB
    g_MqttSendData[Index++] = 4;                           // Protocol Name Length LSB
    g_MqttSendData[Index++] = 'M';                         // ASCII Code for M
    g_MqttSendData[Index++] = 'Q';                         // ASCII Code for Q
    g_MqttSendData[Index++] = 'T';                         // ASCII Code for T
    g_MqttSendData[Index++] = 'T';                         // ASCII Code for T
    g_MqttSendData[Index++] = 4;                           // MQTT Protocol version = 4
    g_MqttSendData[Index++] = 0xc2;                        // conn flags
    g_MqttSendData[Index++] = 0;                           // Keep-alive Time Length MSB
    g_MqttSendData[Index++] = 60;                          // Keep-alive Time Length LSB  60S心跳包
    g_MqttSendData[Index++] = (0xff00 & ClientIDLen) >> 8; // Client ID length MSB
    g_MqttSendData[Index++] = 0xff & ClientIDLen;          // Client ID length LSB

    for (i = 0; i < ClientIDLen; i++)
    {
        g_MqttSendData[Index + i] = ClientID[i];
    }
    Index = Index + ClientIDLen;

    if (UsernameLen > 0)
    {
        g_MqttSendData[Index++] = (0xff00 & UsernameLen) >> 8; // username length MSB
        g_MqttSendData[Index++] = 0xff & UsernameLen;          // username length LSB
        for (i = 0; i < UsernameLen; i++)
        {
            g_MqttSendData[Index + i] = Username[i];
        }
        Index = Index + UsernameLen;
    }

    if (PasswordLen > 0)
    {
        g_MqttSendData[Index++] = (0xff00 & PasswordLen) >> 8; // password length MSB
        g_MqttSendData[Index++] = 0xff & PasswordLen;          // password length LSB
        for (i = 0; i < PasswordLen; i++)
        {
            g_MqttSendData[Index + i] = Password[i];
        }
        Index = Index + PasswordLen;
    }
    return Index;
}

/**
 * @brief  MQTT订阅/取消订阅数据打包函数
 * @param  SendData
 * @param  topic                主题
 * @param  qos         消息等级
 * @param  whether     订阅/取消订阅请求包
 * @retval
 * @example
 **/
int MqttSubscribeTopic(char *topic, uint8_t qos, uint8_t whether)
{
    int topiclen = strlen(topic);
    int i = 0, index = 0;

    if (whether)
        g_MqttSendData[index++] = 0x82; // 0x82 //消息类型和标志 SUBSCRIBE 订阅
    else
        g_MqttSendData[index++] = 0xA2; // 0xA2 取消订阅

    g_MqttSendData[index++] = topiclen + 5;             // 剩余长度(不包括固定头部)
    g_MqttSendData[index++] = 0;                        // 消息标识符,高位
    g_MqttSendData[index++] = 0x01;                     // 消息标识符,低位
    g_MqttSendData[index++] = (0xff00 & topiclen) >> 8; // 主题长度(高位在前,低位在后)
    g_MqttSendData[index++] = 0xff & topiclen;          // 主题长度

    for (i = 0; i < topiclen; i++)
    {
        g_MqttSendData[index + i] = topic[i];
    }
    index = index + topiclen;

    if (whether)
    {
        g_MqttSendData[index] = qos; // QoS级别
        index++;
    }
    return index;
}

/**
 * @brief  MQTT发布数据打包函数
 * @param  mqtt_message
 * @param  topic                主题
 * @param  qos         消息等级
 * @retval
 * @example
 **/
int MqttPublishData(char *topic, char *message, uint8_t qos)
{
    int topic_length = strlen(topic);
    int message_length = strlen(message);
    int i, index = 0;
    static uint16_t id = 0;

    g_MqttSendData[index++] = 0x30; // MQTT Message Type PUBLISH  30:消息等级是0  32消息等级是1  34消息等级是2

    if (qos)
        g_MqttSendData[index++] = 2 + topic_length + 2 + message_length; // 数据长度
    else
        g_MqttSendData[index++] = 2 + topic_length + message_length; // Remaining length

    g_MqttSendData[index++] = (0xff00 & topic_length) >> 8; // 主题长度
    g_MqttSendData[index++] = 0xff & topic_length;

    for (i = 0; i < topic_length; i++)
    {
        g_MqttSendData[index + i] = topic[i]; // 拷贝主题
    }
    index += topic_length;

    if (qos)
    {
        g_MqttSendData[index++] = (0xff00 & id) >> 8;
        g_MqttSendData[index++] = 0xff & id;
        id++;
    }

    for (i = 0; i < message_length; i++)
    {
        g_MqttSendData[index + i] = message[i]; // 拷贝数据
    }
    index += message_length;

    return index;
}
